#ifndef __MESSAGE
#define __MESSAGE
#include <stdlib.h>
#include <list>
#include "ICallback.h"
#include "Logic/Vector2D.h"

#define    MODULE_MSG       1<<8
#define    ENTITY_MSG       1<<7
#define    UNICAST_MSG      1<<6
#define    BROADCAST_MSG    1<<5


enum
{
	REGISTER_ERROR_MESSAGE_NOT_IN_SYSTEM = -1,
	REGISTER_ERROR_ALREADY_REGISTERED,
	REGISTER_MESSAGE_OK
};

enum MSGTYPE
{
	MSGTYPE_DEFAULT = -1,
	MSGTYPE_CHANGE_STATE,
	MSGTYPE_ENTITY_MOVE,
	MSGTYPE_ENTITY_STOP,
	MSGTYPE_ENTITY_ATTACK,
	MSGTYPE_ENTITY_HURT
};


class Message
{
public:
    Message(int flag, int type = MSGTYPE_DEFAULT){m_flag = flag;m_typeID = type;m_delivered = false;m_timer = 0.0f;}
    virtual ~Message(){}
    
	int   m_flag;
    int   m_typeID;
    int   m_fromID;
    int   m_toID;
    float m_timer;
    bool  m_delivered;
};

//template message class for data passing
template <typename T>
class DataMessage: public Message
{
public:
    DataMessage(int flag, int type, T data):Message(flag, type){m_dataStorage = data;}
    ~DataMessage(){}

    //data member
    T m_dataStorage;
};

struct LogicMsg
{
	int         type;
	int         time;
	Vector2Di   from;
	Vector2Di   to;
	int         direction;
};

struct MessageReg
{
	MessageReg(){m_objectID = -1;m_parent = NULL; m_Callback = NULL;}
	int       m_objectID;
	void*     m_parent;
	ICallback* m_Callback;
};

typedef std::list<MessageReg*> MessageRegList;

struct MessageType
{
	int            m_typeID;
	MessageRegList m_moduleMessageRegList;
	MessageRegList m_entityMessageRegList;

	//debug data
	char* m_name;
};

#endif